using System;
using System.Linq;

namespace Synapse.Framework.AoP
{
    public class InvocationHandler : IInvocationHandler
    {
        private readonly object realInstance;
        private readonly Type interfaceType;
        private readonly IInterceptorBuilder interceptorBuilder;

        public InvocationHandler(object realObject, Type interfaceType, IInterceptorBuilder interceptorBuilder)
        {
            realInstance = realObject;
            this.interfaceType = interfaceType;
            this.interceptorBuilder = interceptorBuilder;
            interceptorBuilder.Define(realInstance.GetType());
        }

       
        public object Invoke(string methodHandle, object[] values)
        {
            var methodInfoInstance =  realInstance.GetType().GetMethods().SingleOrDefault(i => i.Name == methodHandle);
            var methodInfoType = interfaceType.GetMethods().SingleOrDefault(i => i.Name == methodHandle);
            var methodInfo = methodInfoInstance ?? methodInfoType;
            IInvocation invocation = new Invocation(realInstance, methodInfo, values);
            interceptorBuilder
                .Define(methodInfo)
                .Intercept(invocation);
            return invocation.ReturnValue;
        }
    }
}